#include <iostream>
#include <memory>

// 代理模式 通过代理类 来控制实际对象的访问权限
//
// 委托类 实际执行代码的对象
// 代理类 可以添加额外逻辑，内部持有委托类（组合）
// 用户 用户不直接访问委托类 而是与代理类打交道
class VideoSite {
public:
    virtual void free() = 0;
    virtual void vip() = 0;
    virtual void ticket() = 0;
    virtual ~VideoSite() {
    }
};

// 一个具有所有权限的派生类
class AllVideoSite : public VideoSite {
public:
    void free() {
        std::cout << "free" << std::endl;
    }
    void vip() {
        std::cout << "vip" << std::endl;
    }
    void ticket() {
        std::cout << "ticket" << std::endl;
    }
};

// 一个仅有部分权限的 代理类
class FreeVideoSiteProxy : public VideoSite {
public:
    FreeVideoSiteProxy() {
        _vs = new AllVideoSite;
    }
    ~FreeVideoSiteProxy() {
        delete _vs;
    }

    void free() {
        // do something else
        _vs->free();
    }
    void vip() {
        std::cout << "permission denied!" << std::endl;
    }
    void ticket() {
        std::cout << "permission denied!" << std::endl;
    }

private:
    VideoSite* _vs;
};
int main() {
    std::unique_ptr<VideoSite> p = std::make_unique<AllVideoSite>();
    std::unique_ptr<VideoSite> p2 = std::make_unique<FreeVideoSiteProxy>();

    p->free();
    p->vip();
    p->ticket();

    p2->free();
    p2->vip();
    p2->ticket();
}
